package com.itlong.cloud.controller.finance;

import com.itlong.cloud.POJO.DTO.property.PropertyAccountGetDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.property.PropertyAccountDetailVO;
import com.itlong.cloud.POJO.VO.property.PropertyPaymentVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.abstracts.BaseController;
import com.itlong.cloud.annotation.AuthAccessRequired;
import com.itlong.cloud.enumerate.BillTypeEnum;
import com.itlong.cloud.enumerate.FileCatalogEnum;
import com.itlong.cloud.enumerate.OriginPayEnum;
import com.itlong.cloud.enumerate.PaymentTypeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.PropertyErrorCodeEnum;
import com.itlong.cloud.iottp.IIotTpSmsServiceClient;
import com.itlong.cloud.project.property.IPropertyAccountServiceClient;
import com.itlong.cloud.project.property.IPropertyRuleServiceClient;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.operate.IOperatePropertyAccountServiceClient;
import com.itlong.cloud.user.property.IPropertyUserServiceClient;
import com.itlong.cloud.utils.file.UploadFileUtil;
import com.itlong.cloud.utils.network.http.HttpProtocolUtil;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * <desc>
 *      运营系统收费管理运营账单模块聚合Controller。
 * </desc>
 * @createDate 2019/05/28
 */
@RestController
@RequestMapping(path = "/expenses/account")
@RefreshScope
public class OperateAccountController extends BaseController {

    private static Logger LOG = LoggerFactory.getLogger(OperateAccountController.class);

    @Value("${" + PlatformConstants.FILE_FTP_HOST + "}")
    public String FILE_FTP_HOST;

    @Value("${" + PlatformConstants.FILE_FTP_PORT + "}")
    public String FILE_FTP_PORT;

    @Value("${" + PlatformConstants.FILE_FTP_USERNAME + "}")
    public String FILE_FTP_USERNAME;

    @Value("${" + PlatformConstants.FILE_FTP_PASSWORD + "}")
    public String FILE_FTP_PASSWORD;

    @Value("${" + PlatformConstants.FILE_ACCESS_URL + "}")
    public String FILE_ACCESS_URL;

    @Value("${" + PlatformConstants.PROJECT_STATIC_FILE_PATH + "}")
    public String PROJECT_STATIC_FILE_PATH;

    @Autowired
    IPropertyAccountServiceClient iPropertyAccountServiceClient;

    @Autowired
    IIotTpSmsServiceClient iIotTpSmsServiceClient;

    @Autowired
    IPropertyUserServiceClient iPropertyUserServiceClient;

    @Autowired
    IOperatePropertyAccountServiceClient iOperatePropertyAccountServiceClient;

    @Autowired
    IPropertyRuleServiceClient iPropertyRuleServiceClient;


    /**
     * <desc>
     *      分页查询运营账单
     * <desc/>
     *
     * @param propertyAccountGetDTO 查询未缴费数据
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/28
     */
    @RequestMapping(path = "getOperateBillByPage", method = RequestMethod.POST)
    @ResponseBody
    @AuthAccessRequired
    public Object getOperateBillByPage(PropertyAccountGetDTO propertyAccountGetDTO) {
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAccountGetDTO= HttpProtocolUtil.parseRequestParamToDTO(PropertyAccountGetDTO.class,request);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), iPropertyAccountServiceClient.getOperateBillByPage(propertyAccountGetDTO));
        } catch (Exception e) {
            throw new DataAccessException(String.format(
                    "【运营系统_收费管理_分页查询运营账单】分页查询运营账单失败"), e);
        }
    }
    /**
     * <desc>
     *      导出账单
     * <desc/>
     *
     * @param propertyAccountGetDTO 查询条件
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/28
     */
    @RequestMapping(path = "/exportPayment", method = RequestMethod.POST)
    @ResponseBody
    @AuthAccessRequired
    public Object exportPayment(PropertyAccountGetDTO propertyAccountGetDTO) {
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            propertyAccountGetDTO= HttpProtocolUtil.parseRequestParamToDTO(PropertyAccountGetDTO.class,request);
            Path excelFilePath = Paths.get(PROJECT_STATIC_FILE_PATH, PlatformConstants.OPERATE_PAYMENT_EXORT_EXPORT_FILE);
            if (!new File(excelFilePath.toString()).exists()) {  //模板文件不存在
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_TMPLATE_FILE_PATH_NOT_EXISTS_ERR.getErrorCode());
            }
            List<PropertyPaymentVO> result =
                    iPropertyAccountServiceClient.getOperatePaymentByFeeIds(propertyAccountGetDTO);
            //创建Excel操作对象，07之前版本(*.xls)使用HSSFWorkBook 07之后版本使用（*.xlsx）XSSFWorkbook
            try (InputStream excelFileStream = new FileInputStream(excelFilePath.toString())) {

                try (HSSFWorkbook workbook = new HSSFWorkbook(excelFileStream)) {
                    HSSFSheet sheet = workbook.getSheetAt(0);
                    short rowHeght = 420;
                    //移除模板中可能存在的样例数据
                    for (int rowIndex = 1; rowIndex <= 3; rowIndex++) {
                        HSSFRow row = sheet.getRow(rowIndex);
                        if (row != null) {
                            rowHeght = row.getHeight();
                            sheet.removeRow(row);
                        }
                    }

                    for (int index = 0; index < result.size(); index++) {
                        PropertyPaymentVO propertyPaymentVO = result.get(index);
                        int rowIndex = index + 1; //标题行
                        HSSFRow dataRow = sheet.createRow(rowIndex);
                        dataRow.setHeight(rowHeght);
                        HSSFCell noteCell = dataRow.createCell(0);
                        noteCell.setCellValue(propertyPaymentVO.getFeeId());
                        noteCell = dataRow.createCell(1);
                        noteCell.setCellValue(propertyPaymentVO.getProjectId());
                        noteCell = dataRow.createCell(2);
                        noteCell.setCellValue(propertyPaymentVO.getProjectName());
                        noteCell = dataRow.createCell(3);
                        noteCell.setCellValue(propertyPaymentVO.getMonth());
                        noteCell = dataRow.createCell(4);
                        noteCell.setCellValue(propertyPaymentVO.getFeeNumber());
                        noteCell = dataRow.createCell(5);
                        noteCell.setCellValue(propertyPaymentVO.getAddress());
                        noteCell = dataRow.createCell(6);
                        noteCell.setCellValue(propertyPaymentVO.getRealName());
                        noteCell = dataRow.createCell(7);
                        noteCell.setCellValue(propertyPaymentVO.getPhoneNum());
                        noteCell = dataRow.createCell(8);
                        noteCell.setCellValue(BillTypeEnum.getDescription(Integer.parseInt(propertyPaymentVO.getType())));
                        noteCell = dataRow.createCell(9);
                        noteCell.setCellValue(propertyPaymentVO.getDueAmount());
                        noteCell = dataRow.createCell(10);
                        noteCell.setCellValue(propertyPaymentVO.getPenalty());
                        noteCell = dataRow.createCell(11);
                        noteCell.setCellValue(propertyPaymentVO.getPaidAmount());
                        noteCell = dataRow.createCell(12);
                        noteCell.setCellValue("0".equals(propertyPaymentVO.getPaymentCount())?"":propertyPaymentVO.getPaymentCount());
                        noteCell = dataRow.createCell(13);
                        noteCell.setCellValue(propertyPaymentVO.getCreateTime());
                        noteCell = dataRow.createCell(14);
                        noteCell.setCellValue(propertyPaymentVO.getOriginPay() == null?null:OriginPayEnum.getDescription(Integer.parseInt(propertyPaymentVO.getOriginPay())));
                        noteCell = dataRow.createCell(15);
                        noteCell.setCellValue(propertyPaymentVO.getPaymentType() == null?null:PaymentTypeEnum.getDescription(Integer.parseInt(propertyPaymentVO.getPaymentType())));
                        noteCell = dataRow.createCell(16);
                        noteCell.setCellValue(propertyPaymentVO.getPayTime());

                        //Excel格式保护密码
//                        sheet.protectSheet("itlong");
                    }
                    String fileName = String.format("%s_PaymentInfo_%s.xls",
                            propertyAccountGetDTO.getProjectId(),
                            DateFormatUtils.format(new Date(), "yyyyMMddHHmmssSSS"));
                    fileName = URLEncoder.encode(fileName, "UTF-8");

                    ByteArrayOutputStream os = new ByteArrayOutputStream();
                    workbook.write(os);
                    byte[] content = os.toByteArray();
                    InputStream exportFileStream = new ByteArrayInputStream(content);
                    String exportfileUrl = uploadFile(exportFileStream,fileName);
                    if (StringUtils.isBlank(exportfileUrl)){
                        return new MessageVO(PropertyErrorCodeEnum.PROJECT_EXPORT_FILE_SAVE_ERR.getErrorCode());
                    }
                    return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), (Object) exportfileUrl);
                }
            }
        } catch (Exception e) {
            throw new DataAccessException(String.format(
                    "【运营系统_收费管理_导出已缴费账单】导出已缴费账单失败"), e);
        }
    }

    /**
     * <desc>
     *      查看缴费账单明细
     * <desc/>
     *
     * @param feeId 缴费账单ID
     * @param projectId 项目编号
     * @return MessageVO 标准格式化响应结果
     * @author Qiang.S
     * @createDate 2019/05/28
     */
    @RequestMapping(path = "/getAccountDetail", method = RequestMethod.POST)
    @ResponseBody
    public Object getAccountDetail(String feeId, String projectId) {
        try {
            HttpServletRequest request=((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            feeId=request.getAttribute("feeId")==null?null:request.getAttribute("feeId").toString();
            projectId=request.getAttribute("projectId")==null?null:request.getAttribute("projectId").toString();
            if(StringUtils.isBlank(feeId)) {
                return new MessageVO(PropertyErrorCodeEnum.PROJECT_FEEID_EMPTY_ERR.getErrorCode());
            }
            PropertyAccountDetailVO result =
                    iPropertyAccountServiceClient.getAccountDetail(feeId,projectId);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), result);
        } catch (Exception e) {
            throw new DataAccessException(String.format(
                    "【运营系统_收费管理_查看缴费账单明细】查看缴费账单明细失败"), e);
        }
    }

    /**
     * <desc>
     *    Ftp上传文件，返回Url.
     * </desc>
     *
     * @param inputStream 文件流
     * @return 文件上传成功后会返回Url,否则返回空
     * @author Qiang.S
     * @createDate 2019/05/28
     */
    public String uploadFile(InputStream inputStream, String fileName) throws IOException {

        String fileUrl = "";
        String fileType = StringHandlerUtil.copySubStr(fileName, fileName.lastIndexOf('.'), fileName.length());
        UploadFileUtil.UploadFile uploadFileUtil = new UploadFileUtil().new UploadFile(
                FILE_FTP_HOST,
                FILE_FTP_USERNAME,
                FILE_FTP_PASSWORD,
                FILE_FTP_PORT,
                inputStream,
                fileType,
                FILE_ACCESS_URL,
                FileCatalogEnum.ACCOUNTTEMPLATE_FILE.getType()
        );
        Map<String, Object> resultMap = UploadFileUtil.uploadFile(uploadFileUtil);
        Boolean returnCode = (Boolean)resultMap.get("returnCode");
        if (returnCode == false){
            return fileUrl;
        }
        fileUrl = resultMap.get("accessPath").toString();
        return fileUrl;
    }

}